import java.awt.Color;
import java.awt.Graphics;
import java.util.Map;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;
import com.speljohan.rsbot.script.wrappers.RSTilePath;

public class ExemptVarrockFlyFisher extends Script implements PaintListener,
		ServerMessageListener {

	int fishSpot = 328;
	int poleID = 309;
	int featherID = 314;
	int fishID[] = { 331, 335 };
	int bankID = 11402;
	int howMany = 0;
	int nextSpotc = 0;
	int trainStat = Constants.STAT_FISHING;
	int startStatLvl = skills.getCurrentSkillLevel(trainStat);
	int startXp = skills.getCurrentSkillExp(trainStat);
	public long startTime = System.currentTimeMillis();
	Color BG = new Color(70, 234, 40, 100);
	int startExp = skills.getCurrentSkillExp(trainStat);
	RSNPC fishHere = getNearestNPCByID(fishSpot);
	RSTile[] nextSpot = new RSTile[] { new RSTile(3103, 3424),
			new RSTile(3109, 3422) };
	public RSTile[] toBank = new RSTile[] { new RSTile(3103, 3424),
			new RSTile(3103, 3421), new RSTile(3111, 3421),
			new RSTile(3119, 3419), new RSTile(3127, 3415),
			new RSTile(3137, 3417), new RSTile(3147, 3418),
			new RSTile(3155, 3418), new RSTile(3165, 3425),
			new RSTile(3174, 3429), new RSTile(3185, 3230),
			new RSTile(3182, 3438) };
	public RSTilePath walk = new RSTilePath(randomizePath(toBank, 2, 2), this);

	// /////////////////////////////////////////////
	// /////////////////////////////////////////////
	// /////////////////////////////////////////////
	public void fish() {
		if (distanceTo(nextSpot[0]) > 10 && distanceTo(nextSpot[1]) > 10) {
			walkTileMM(randomizeTile(toBank[toBank.length - 2], 2, 2));
			try {
				walk.walkToStart();
			} catch (final Exception e) {
				e.printStackTrace();
			}
		}
		if (!getMyPlayer().isMoving() && getMyPlayer().getAnimation() == -1) {
			fishHere = getNearestNPCByID(fishSpot);
			if (fishHere != null) {
				turnToTile(fishHere.getLocation());
				atNPC(fishHere, "Lure");
				wait(random(500, 1000));
			} else {
				if (nextSpotc == 0) {
					nextSpotc++;
				} else {
					nextSpotc = 0;
				}
				walkTileMM(nextSpot[nextSpotc]);
			}
		}
	}

	@Override
	public String getAuthor() {
		return "Exempt";
	}

	@Override
	public String getName() {
		return "ExemptVarrockFlyFisher";
	}

	@Override
	public String getScriptCategory() {
		return "Fishing";
	}

	@Override
	public String getScriptDescription() {
		String html = "";

		html += "<html>";
		html += "<body>";
		html += "<font size=\"8\">";
		html += "<b>" + getName() + " v" + getVersion() + "</b><br>";
		html += "<font size=\"6\">";
		html += "Author: " + getAuthor() + "<br><br>";
		html += "<font size=\"4\">";
		html += "Be sure to run this in the varrock west bank with feathers and a fly fishing rod.<br>";
		html += "</font>";
		html += "</body>";
		html += "</html>";

		return html;
	}

	@Override
	public double getVersion() {
		return 2.0;
	}

	@Override
	public int loop() {
		if (getInventoryCount(featherID) > 0) {
			walkTo();
		} else {
			log("Out of feathers.");
			stopAllScripts();
		}
		return random(500, 1000);
	}

	@Override
	public void onFinish() {
		Bot.getEventManager().removeListener(PaintListener.class, this);
		Bot.getEventManager().removeListener(ServerMessageListener.class, this);
		log("Exiting the script now");
	}

	public void onRepaint(final Graphics g) {
		if (isLoggedIn()) {
			long millis = System.currentTimeMillis() - startTime;
			final long hours = millis / (1000 * 60 * 60);
			millis -= hours * 1000 * 60 * 60;
			final long minutes = millis / (1000 * 60);
			millis -= minutes * 1000 * 60;
			final long seconds = millis / 1000;
			final int LevelChange = skills.getCurrentSkillLevel(trainStat)
					- startStatLvl;
			final int XPChange = skills.getCurrentSkillExp(trainStat) - startXp;
			float xpPerSec = 0;
			if ((minutes > 0 || hours > 0 || seconds > 0) && XPChange > 0) {
				xpPerSec = (float) XPChange
						/ (float) (seconds + minutes * 60 + hours * 60 * 60);
			}
			final float xpPerMin = xpPerSec * 60;
			final float xpPerHour = xpPerMin * 60;
			final float timeTillLvl = 9999;
			float secsTillLvl = (int) timeTillLvl;
			float minsTillLvl = (int) timeTillLvl;
			float hoursTillLvl = (int) timeTillLvl;
			if (xpPerSec > 0) {
				secsTillLvl = skills.getXPToNextLevel(trainStat) / xpPerSec;
			}
			if (xpPerMin > 0) {
				minsTillLvl = skills.getXPToNextLevel(trainStat) / xpPerMin;
			}
			if (xpPerHour > 0) {
				hoursTillLvl = skills.getXPToNextLevel(trainStat) / xpPerHour;
			}
			secsTillLvl -= (int) minsTillLvl * 60;
			minsTillLvl -= (int) hoursTillLvl * 60;

			if (minsTillLvl < 0) {
				minsTillLvl = 0;
			}
			g.setColor(BG);
			g.fill3DRect(330, 20, 184, 75, true);
			g.setColor(Color.black);
			g.drawString("ExemptVarrockFlyFisher v2.0", 334, 38);
			g.drawString("Runtime: " + hours + "h " + minutes + "m " + seconds
					+ "s ", 334, 48);
			g.drawString("Levels Gained: " + LevelChange, 334, 58);
			g
					.drawString("Exp Gained: "
							+ (skills.getCurrentSkillExp(trainStat) - startXp),
							334, 68);
			g.drawString("Exp/Hr: " + (int) xpPerHour, 334, 78);
			g.drawString("Amount Caught: " + howMany, 334, 88);
		}
	}

	@Override
	public boolean onStart(final Map<String, String> args) {
		log("Starting ExemptVarrockFlyFisher v2.0");
		return true;
	}

	public void serverMessageRecieved(final ServerMessageEvent e) {
		final String word = e.getMessage().toLowerCase();
		if (word.contains("trout") || word.contains("salmon")) {
			howMany++;
		}
	}

	public void useBank() {
		if (findObject(bankID) != null) {
			final RSObject booth = findObject(bankID);
			atObject(booth, "Use-quickly");
			wait(random(500, 1000));
			if (RSInterface.getInterface(Constants.INTERFACE_BANK).isValid()) {
				bank.depositAllExcept(poleID, featherID);
			}
		} else {
			wait(random(500, 1000));
		}
	}

	public void walkTo() {
		if (getEnergy() >= random(15, 25)) {
			setRun(true);
		}
		if (getInventoryCount() > 27) {
			nextSpotc = 0;
			walkTileMM(randomizeTile(toBank[2], 2, 2));
			try {
				walk.walkToEnd();
			} catch (final Exception e) {
				e.printStackTrace();
			}
			wait(random(500, 1000));
			if (getMyPlayer().isMoving() == false) {
				useBank();
			}
		} else {
			fish();
		}
	}
}